package com.flute.haflute.agent.heartbeat;

import java.util.ArrayList;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Timer;
import java.util.TimerTask;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.flute.haflute.agent.manage.ClusterResourceCenter;
import com.flute.haflute.agent.topo.ClusterTopoDBService;
import com.flute.haflute.agent.topo.Node;
import com.flute.haflute.common.ClusterContext;

/**
 * 巡检心跳状态的后台服务<br>
 * 定期检查所有节点的心跳状态，并更新拓扑和集群状态
 */
public class HeartBeatWatcher {

	private static Logger logger = LoggerFactory
			.getLogger(HeartBeatWatcher.class);

	/** period 检查心跳状态的时间间隔 */
	private final long period;

	/** topoService 拓扑数据库服务 */
	private ClusterTopoDBService topoService;

	public static HeartBeatWatcher newInstance() {
		return new HeartBeatWatcher();
	}

	private HeartBeatWatcher() {
		period = ClusterContext.getHeartBeatInterval()
				* ClusterContext.getHeartBeatFailures()
				+ ClusterContext.getHeartBeatInterval() / 10;
		topoService = ClusterTopoDBService.getInstance();
	}

	public void startWatch() {
		new Timer("HeartBeat Watcher").schedule(new Checker(), period, period);
	}

	private class Checker extends TimerTask {

		/*
		 * @see java.util.TimerTask#run()
		 */
		@Override
		public void run() {
			long current = System.currentTimeMillis();
			ArrayList<Node> lostNodes = new ArrayList<Node>();
			Map<Node, HeartBeatState> db = topoService.getNeighborStateDB();
			for (Entry<Node, HeartBeatState> entry : db.entrySet()) {
				HeartBeatState state = entry.getValue();
				// 如果心跳的活动时间大于巡检的时间间隔，则说明该节点已经失效
				if (current - state.getActiveTime() > period) {
					lostNodes.add(entry.getKey());
				}
			}

			for (Node node : lostNodes) {
				ClusterResourceCenter.removeNode(node);
				logger.info("LOST one node : {}", node);
			}

			notifyDM(lostNodes);
		}

		private void notifyDM(ArrayList<Node> lostNodes) {
			// TODO Auto-generated method stub

		}
	}
}
